﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports Newtonsoft.Json
Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace roncliProductions.LibWowArmory

    ''' <summary>
    ''' A class that defines the events for a given month on a player's calendar
    ''' </summary>
    ''' <remarks></remarks>
    Public Class CalendarMonthUser
        Inherits WowArmoryData

        Private cmuCalendar As New CalendarMonthUserSchema.calendarMonthUser
        Private eEvents As New List(Of [Event])
        Private strRealm As String
        Private strName As String
        Private dtMonth As Date

        ''' <summary>
        ''' The realm of the character for the calendar to lookup
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm() As String
            Get
                Return strRealm
            End Get
            Set(ByVal value As String)
                strRealm = value
            End Set
        End Property

        ''' <summary>
        ''' The name of the character for the calendar to lookup
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name() As String
            Get
                Return strName
            End Get
            Set(ByVal value As String)
                strName = value
            End Set
        End Property

        ''' <summary>
        ''' The month of the character's calendar to lookup.  Note that only month and year are stored.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Month() As Date
            Get
                Return dtMonth
            End Get
            Set(ByVal value As Date)
                dtMonth = New Date(value.Year, value.Month, 1)
            End Set
        End Property

        ''' <summary>
        ''' The URL that will be used to retrieve the character's calendar from the armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL() As String
            Get
                Return String.Format("http://www.wowarmory.com/vault/calendar/month-user.json?callback=calendar.loadEvents&r={0}&n={1}&year={2}&month={3}&loc=en_us", strRealm, strName, dtMonth.Year, dtMonth.Month)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request requires login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin() As Boolean
            Get
                Return True
            End Get
        End Property

        ''' <summary>
        ''' The month's calendar type
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CalendarType() As String
            Get
                Return cmuCalendar.calendarType
            End Get
        End Property

        ''' <summary>
        ''' The timezone offset of the event's server
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property TimezoneOffset() As TimeSpan
            Get
                Return New TimeSpan(0, 0, 0, 0, CInt(cmuCalendar.tz))
            End Get
        End Property

        ''' <summary>
        ''' The list of events for the month
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Events() As List(Of [Event])
            Get
                Return eEvents
            End Get
            Set(ByVal value As List(Of [Event]))
                eEvents = value
            End Set
        End Property

        ''' <summary>
        ''' A constructor to create a new calendar month for a character
        ''' </summary>
        ''' <param name="strUsername">The World of Warcraft/battle.net account username</param>
        ''' <param name="strPassword">The World of Warcraft/battle.net account password</param>
        ''' <param name="strRealm">The realm of the character for the calendar to lookup</param>
        ''' <param name="strName">The name of the character for the calendar to lookup</param>
        ''' <param name="dtMonth">The month of the character's calendar to lookup.  Note that only month and year are stored.</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal strUsername As String, ByVal strPassword As String, ByVal strRealm As String, ByVal strName As String, ByVal dtMonth As Date)
            Me.Username = strUsername
            Me.Password = strPassword
            Me.strRealm = strRealm
            Me.strName = strName
            Me.Month = dtMonth
            Load()
        End Sub

        ''' <summary>
        ''' Loads and deserialzes the JSON data
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            MyBase.Retrieve()

            strData = Regex.Match(strData, "calendar.loadEvents\((.*)\);").Groups(1).Value

            cmuCalendar = CType(JsonConvert.DeserializeObject(strData, GetType(CalendarMonthUserSchema.calendarMonthUser)), CalendarMonthUserSchema.calendarMonthUser)

            eEvents.Clear()

            If cmuCalendar Is Nothing Then
                Throw New InvalidOperationException("The calendar did not return any information.")
                Exit Sub
            End If

            If cmuCalendar.events Is Nothing Then
                Exit Sub
            End If

            For Each eEvent As CalendarMonthUserSchema.event In cmuCalendar.events
                eEvents.Add(New [Event](eEvent.calendarType, eEvent.icon, eEvent.id, eEvent.moderator, eEvent.start, eEvent.status, eEvent.summary, eEvent.type, Me))
            Next
        End Sub

        ''' <summary>
        ''' A class that defines an event
        ''' </summary>
        ''' <remarks></remarks>
        Public Class [Event]
            Private strCalendarType As String
            Private strIcon As String
            Private intID As Integer
            Private blnModerator As Boolean
            Private lngStart As Long
            Private strStatus As String
            Private strSummary As String
            Private strType As String
            Private cmuParent As CalendarMonthUser

            ''' <summary>
            ''' Contains further detail about the calendar event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property CalendarDetail() As CalendarDetail
                Get
                    Return New CalendarDetail(cmuParent.Username, cmuParent.Password, cmuParent.Realm, cmuParent.Name, intID)
                End Get
            End Property

            ''' <summary>
            ''' The calendar type of the calendar event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property CalendarType() As String
                Get
                    Return strCalendarType
                End Get
            End Property

            ''' <summary>
            ''' The icon of the calendar event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Icon() As String
                Get
                    Return strIcon
                End Get
            End Property

            ''' <summary>
            ''' The identification number of the event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property ID() As Integer
                Get
                    Return intID
                End Get
            End Property

            ''' <summary>
            ''' Determines whether or not the character is a moderator for the event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Moderator() As Boolean
                Get
                    Return blnModerator
                End Get
            End Property

            ''' <summary>
            ''' The date of the event, in UTC
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property UTCStart() As Date
                Get
                    Return New Date(1970, 1, 1).AddMilliseconds(lngStart)
                End Get
            End Property

            ''' <summary>
            ''' The character's invitation status for the calendar event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Status() As String
                Get
                    Return strStatus
                End Get
            End Property

            ''' <summary>
            ''' The summary of the calendar event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Summary() As String
                Get
                    Return strSummary
                End Get
            End Property

            ''' <summary>
            ''' The type of calendar event
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Type() As String
                Get
                    Return strType
                End Get
            End Property

            ''' <summary>
            ''' The date of the event, in local server time
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Start() As Date
                Get
                    Return New Date(1970, 1, 1).AddMilliseconds(lngStart).Add(cmuParent.TimezoneOffset)
                End Get
            End Property

            ''' <summary>
            ''' A constructor to create a new calendar event
            ''' </summary>
            ''' <param name="strCalendarType"></param>
            ''' <param name="strIcon"></param>
            ''' <param name="intID"></param>
            ''' <param name="blnModerator"></param>
            ''' <param name="lngStart"></param>
            ''' <param name="strStatus"></param>
            ''' <param name="strSummary"></param>
            ''' <param name="strType"></param>
            ''' <param name="cmuParent"></param>
            ''' <remarks></remarks>
            Public Sub New(ByVal strCalendarType As String, ByVal strIcon As String, ByVal intID As Integer, ByVal blnModerator As Boolean, ByVal lngStart As Long, ByVal strStatus As String, ByVal strSummary As String, ByVal strType As String, ByRef cmuParent As CalendarMonthUser)
                Me.strCalendarType = strCalendarType
                Me.strIcon = strIcon
                Me.intID = intID
                Me.blnModerator = blnModerator
                Me.lngStart = lngStart
                Me.strStatus = strStatus
                Me.strSummary = strSummary
                Me.strType = strType
                Me.cmuParent = cmuParent
            End Sub

        End Class

    End Class

End Namespace